昨天把 TurtleBot3 的轉向、前進與停止條件整合在一起,接下來就要到 Gazebo 中,確認機器人動起來時的反應。
紅色方塊持續移動時,它在畫面中的位置和大小也會改變。我想先觀察機器人能不能跟著調整方向,以及前進和停止之間的切換會不會太頻繁。今天就先整理測試時要看的幾種情況。
每次收到一張相機影像,程式就會重新尋找紅色目標。找到時,計算 error_x 和 box_area,再根據前一天設定的條件,決定轉向、前進或停止。如果這一幀沒有找到目標,就發布停止指令。
例如上一幀的方塊還在中央,面積也小於停止門檻,機器人會往前走;下一幀方塊偏到旁邊、超出死區,就要停止前進並調整方向。等到目標回到中央附近,再重新判斷是否需要靠近。
這個過程會隨著收到的影像一直重複,所以測試時也要連續觀察,看看目標位置改變後,機器人的動作有沒有跟著更新。
先沿用 Day 11 的判斷條件,把要測試的情況列出來:
| 畫面中的情況 | 預期的機器人動作 |
|---|---|
| 找到目標,水平誤差在死區內,面積小於停止門檻 | 不轉向,以設定速度前進 |
| 找到目標,但水平誤差超出死區 | 停止前進,調整轉向 |
| 目標在死區內,面積達到停止門檻 | 停止前進與轉向 |
| 影像中沒有找到紅色方塊 | 停止前進與轉向 |
我會先分別確認這幾種情況,再觀察紅色方塊持續移動時的反應。例如機器人原本正在前進,目標突然移向右側,這時是否會停止前進並改為向右轉;等方塊回到中央,是否會依照面積重新決定要不要往前走。
依照目前的程式,即使目標面積已經達到停止門檻,只要水平誤差超出死區,機器人仍然會原地轉向。觀察時要把停止前進和停止轉向分開看。
如果 TurtleBot3 突然不往前走,只看 Gazebo 畫面,有時候不容易知道是哪個條件影響了動作。可能是方塊已經夠大,也可能是目標偏離中央,或是這一幀沒有辨識到方塊。
這時可以一起查看程式中的數值:
| 數值 | 用來確認什麼 |
|---|---|
error_x |
目標偏離畫面中心多少,是否超出死區 |
box_area |
目標外接框的面積,是否達到停止門檻 |
linear.x |
發布的前進速度是多少 |
angular.z |
發布的轉向方向與速度 |
error_x 和 box_area 可以由追蹤程式輸出;發布到 /cmd_vel 的速度訊息,則可以在終端機輸入以下指令查看:
ros2 topic echo /cmd_vel
例如目標超出死區時,可以檢查 linear.x 是否變成 0,以及 angular.z 是否有對應的轉向指令。目標消失時,則要確認兩個值都變成 0。
/cmd_vel 顯示的是程式發布的速度指令,還需要和 Gazebo 中的實際動作一起對照,才能確認機器人有沒有照著指令移動。
前面加入 Dead Zone(死區)後,目標接近中央時就不需要一直微調。但如果目標剛好在死區邊界附近,辨識出的數值只差幾個像素,就可能讓判斷結果改變。
以正負 30 像素的死區為例,先假設每一幀都有找到方塊,而且面積都小於停止門檻:
error_x |
判斷結果 | 機器人的動作 |
|---|---|---|
| 29 | 在死區內 | 前進,不轉向 |
| 32 | 超出死區 | 停止前進,調整轉向 |
| 28 | 回到死區內 | 再次前進,不轉向 |
這三個數值很接近,程式卻會在前進和轉向之間切換。最大角速度限制可以控制轉向的速度,但只要誤差跨過死區邊界,仍然會重新決定動作。
目標面積也可能遇到相同的情況。當方塊位於死區內,box_area 又一直在停止門檻附近變動,前進速度就可能反覆在 FORWARD_SPEED 和 0 之間切換,出現走一下、停一下的動作。
如果測試時遇到這種情況,我會先把切換前後的數值記下來,確認是不是剛好跨過門檻,再決定要調整哪個部分。
這次會先保留目前的參數,記錄動作發生時的情況。例如方塊移到哪個位置時,機器人開始反覆轉向;或是目標接近什麼大小時,前進速度一直在變化。再對照當時的 error_x、box_area 和發布的速度,找出需要檢查的條件。
因為之後想用來做移動跟拍,我也會一起看相機畫面。機器人突然前進、停止,或是一直左右修正時,畫面可能會跟著晃動,這些都是後續調整時要留意的地方。
等到確認問題出現的情況,再一次調整一個設定,比較修改前後的反應。這樣才比較容易知道,這次的變化和哪個參數有關。
error_x、box_area 和 /cmd_vel,確認控制條件。下一篇會從死區與面積門檻附近的反覆切換開始,研究能不能調整判斷方式,減少機器人走一下、停一下的情況。